import regex,string
from CharStyles import *

class MyRegex:
	def __init__(self,pat,ignorecase=None):
		self.pat=pat
		if ignorecase:
			self.regex=regex.compile(pat,string.upper(string.maketrans('','')))
		else:
			self.regex=regex.compile(pat)
			
		self.search=self.regex.search
	def __repr__(self):
		return "Regex(%s)" % `self.pat`
	def matched(self):
		return self.regex.regs[0]
	def __getattr__(self,name):
		return getattr(self.regex,name)
class GroupRegex(MyRegex):
	def __init__(self,pat,group,ignorecase=None):
		MyRegex.__init__(self,pat,ignorecase)
		self.group=group
	def matched(self):
		return self.regex.regs[self.group]
class PairMatcher:
	def __init__(self,open,close):
		self.open=open
		self.close=close
		self.lastmatch=(-1,-1)
	def __repr__(self):
		return "PairMatcher(%s,%s)" % (`self.open`,`self.close`)
	def search(self,str,start):
		s=string.find(str,self.open,start)
		if s>=0:
			e=string.find(str,self.close,s+len(self.open))
			if e>=0:
				self.lastmatch=(s,e+len(self.close))
				return s
		return -1
	def matched(self):
		return self.lastmatch
class _Matcher:
	pos=-1
	def __init__(self,substr):
		self.substr=substr
		self.len=len(substr)
	def __repr__(self):
		return "Matcher(%s,%d)"%(`self.substr`,self.pos)
class PairMatcherWithIgnore:
	def __init__(self,open,close,ignorestrings):
		self.open=open
		self.lastmatch=(-1,-1)
		self.close=_Matcher(close)

		self.ignorestrings=[self.close]
		for pat in ignorestrings:
			self.ignorestrings.append(_Matcher(pat))
	def search(self,str,start):
		s=string.find(str,self.open,start)
		if s<0:
			return -1
		start=s+len(self.open)
		find =string.find
		items=self.ignorestrings[:]
		while start>=0:
			found=None
			foundpos=0x0FFFFFF
			for m in items[:]:
				pos=m.pos
				if pos<foundpos:
					m.pos=pos=find(str, m.substr,start)
				if pos<0:
					del items[items.index(m)]
				elif pos<foundpos:
					found=m
					foundpos=pos
			if not found:
				return -1
			if found==self.close:
				self.lastmatch=(s,found.pos+found.len)
				return s
			start=found.pos+found.len
		return -1
	def matched(self):
		return self.lastmatch

def SyntaxDesc(*syntax_list):
	return syntax_list
def Words(charstyle,word,*words):
	reg=string.join((word,)+words,"\|")
	return (charstyle,GroupRegex("\(^\|[^A-Za-z0-9_]\)\("+reg+"\)[^A-Za-z0-9_]",2))
def WordsCaseInsensitive(charstyle,word,*words):
	reg=string.join((word,)+words,"\|")
	return (
		charstyle,
		GroupRegex(
			"\(^\|[^A-Za-z0-9_]\)\("+reg+"\)[^A-Za-z0-9_]",
			2,
			ignorecase=1
		)
	)
def Regex(charstyle,patt,group=0,ignorecase=None):
	if group:
		return (charstyle,GroupRegex(patt,group,ignorecase))
	else:
		return (charstyle,MyRegex(patt,ignorecase))
def MatchPair(charstyle,open,close,*ignorestrings):
	if ignorestrings:
		return (charstyle,PairMatcherWithIgnore(open,close,ignorestrings))
	else:
		return (charstyle,PairMatcher(open,close))

class NeverMatcher:
	def search(self,str,start):
		"""do not match anything"""
		return -1
	def matched(self):
		return (-1,-1)

def IfCommentHighlight(matcher):
	import SyntaxHighlight
	if SyntaxHighlight.highlight_comments:
		return matcher
	else:
		return (None,NeverMatcher())
